package cn.signalpha.modules.com.service;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.signalpha.common.constant.MsgConstant;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.support.Kv;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.entity.Withdraw;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.com.mapper.WithdrawMapper;
import cn.signalpha.modules.com.vo.WithdrawVO;
import cn.signalpha.modules.shop.service.SellerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 服务类
 *
 * @author signalpha
 */
@Service
@AllArgsConstructor
public class WithdrawService extends ServiceImpl<WithdrawMapper, Withdraw> {

	private final UserService userService;
	private final SellerService sellerService;

	/**
	 * 自定义分页
	 */
	public IPage<WithdrawVO> selectWithdrawUserPage(IPage<WithdrawVO> page, Map<String, Object> params) {
		return page.setRecords(baseMapper.selectWithdrawUserPage(page, params));
	}

	/**
	 * 自定义分页
	 */
	public IPage<WithdrawVO> selectWithdrawSellerPage(IPage<WithdrawVO> page, Map<String, Object> params) {
		return page.setRecords(baseMapper.selectWithdrawSellerPage(page, params));
	}

	/**
	 * 金额统计
	 */
	public Double sumAmount(Date beginTime, Date endTime) {
		return sumAmount(Kv.create().set("beginTime", beginTime).set("endTime", endTime));
	}

	/**
	 * 金额统计
	 */
	public Double sumAmount(Map<String, Object> params) {
		QueryWrapper<Withdraw> wrapper = Wrappers.query();
		wrapper.select("ifnull(sum(amount),0) as total");
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("userId")), Withdraw::getUserId, params.get("userId"));
		wrapper.lambda().ge(ObjectUtil.isNotEmpty(params.get("beginTime")), Withdraw::getCreateTime, params.get("beginTime"));
		wrapper.lambda().le(ObjectUtil.isNotEmpty(params.get("endTime")), Withdraw::getCreateTime, params.get("endTime"));
		return Double.valueOf(getMap(wrapper).get("total").toString());
	}

	/**
	 * 提现审核
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean audit(Long id, Integer status, String remark) {
		Date data = new Date();
		Withdraw withdraw = getById(id);
		Assert.isNull(withdraw, MsgConstant.OBJECT_NULL);
		if(withdraw.getStatus() != 0){throw new ServiceException("请不要重复审核");}
		if(status == -1){
			withdrawRefund(withdraw);
			updateById(Withdraw.builder().id(withdraw.getId()).status(3).remark(remark).auditTime(data).build());
		}else{
			//进入代付流程
			Map<String, Object> resultMap = pay(withdraw);
			Map<String, Object> dataMap = (Map<String, Object>) resultMap.get("data");
			if(ObjectUtil.isEmpty(resultMap.get("statusCode")) || "2002".equals(String.valueOf(resultMap.get("statusCode")))){
				withdrawRefund(withdraw);
				updateById(Withdraw.builder().id(withdraw.getId()).status(3).remark(MapUtil.getStr(dataMap, "errorDesc")).apiRemark(JsonUtil.toJson(resultMap)).auditTime(new Date()).build());
			}else {
				String bizOrderNo = String.valueOf(dataMap.get("merchantOrderNo"));
				updateById(Withdraw.builder().id(withdraw.getId()).bizOrderNo(bizOrderNo).status(1).auditTime(new Date()).build());
			}
		}
		return true;
	}

	/**
	 * 提现退回
	 */
	@Transactional(rollbackFor = Exception.class)
	private void withdrawRefund(Withdraw withdraw) {
		if(withdraw.getCategory() == 1){
			userService.updateUserMoney(WalletDTO.builder()
				.userId(withdraw.getUserId())
				.amount(NumberUtil.add(withdraw.getAmount(), withdraw.getSubAmount()))
				.type(WalletTypeEnum.ADD.getType())
				.sourceId(withdraw.getId().toString())
				.sourceType(WalletSourceEnum.WITHDRAW_REJECT.getType())
				.remark(WalletSourceEnum.WITHDRAW_REJECT.getName())
				.build());
		}else{
			sellerService.updateSellerMoney(WalletDTO.builder()
				.userId(withdraw.getUserId())
				.amount(NumberUtil.add(withdraw.getAmount(), withdraw.getSubAmount()))
				.type(WalletTypeEnum.ADD.getType())
				.sourceId(withdraw.getId().toString())
				.sourceType(WalletSourceEnum.WITHDRAW_REJECT.getType())
				.remark(WalletSourceEnum.WITHDRAW_REJECT.getName())
				.build());
		}
	}

	/**
	 * 代付打款
	 */
	public Map<String, Object> pay(Withdraw withdraw) {
		return new HashMap<>();
	}

	/**
	 * 打款查询
	 */
	public void payQuery(Withdraw withdraw) {
	}

}
